﻿using System;

namespace UtilZ.Dotnet.Ex.Log
{
    /// <summary>
    /// 日志记录器
    /// </summary>
    public sealed class LogerCore : LogerCoreAbs
    {
        /// <summary>
        /// true:异步写日志;false:同步写日志
        /// </summary>
        private readonly bool _asynOutput;

        /// <summary>
        /// 日志分发线程队列
        /// </summary>
        private readonly LogAsynQueue<LogItem> _logDispatcherQueue;

        /// <summary>
        /// 构造函数初始化
        /// </summary>
        /// <param name="asynOutput">true:异步写日志;false:同步写日志</param>
        public LogerCore(bool asynOutput)
            : base()
        {
            this._asynOutput = asynOutput;
            if (asynOutput)
            {
                this._logDispatcherQueue = new LogAsynQueue<LogItem>(this.WriteLog, "日志记录线程");
            }
        }

        private void WriteLog(LogItem item)
        {
            lock (base._appendersLock)
            {
                foreach (var appender in base._appenders)
                {
                    try
                    {
                        appender.WriteLog(item);
                    }
                    catch (Exception exi)
                    {
                        LogSysInnerLog.OnRaiseLog(this, exi);
                    }
                }
            }
        }




        #region ILoger接口
        /// <summary>
        /// 实例添加日志
        /// </summary>
        /// <param name="logItem">日志项</param>
        protected override void PrimitiveLog(LogItem logItem)
        {
            try
            {
                if (!this.Enable || logItem.Level < this.Level)
                {
                    return;
                }

                logItem.LogerName = base._name;
                if (this._asynOutput)
                {
                    this._logDispatcherQueue.Enqueue(logItem);
                }
                else
                {
                    this.WriteLog(logItem);
                }
            }
            catch (Exception exi)
            {
                LogSysInnerLog.OnRaiseLog(this, exi);
            }
        }
        #endregion

        /// <summary>
        /// 释放资源方法
        /// </summary>
        /// <param name="isDisposing">是否释放标识</param>
        protected override void Dispose(bool isDisposing)
        {
            if (this._asynOutput)
            {
                this._logDispatcherQueue.Dispose();
            }

            lock (this._appendersLock)
            {
                foreach (var appender in this._appenders)
                {
                    try
                    {
                        appender.Dispose();
                    }
                    catch (Exception ex)
                    {
                        LogSysInnerLog.OnRaiseLog(this, ex);
                    }
                }
            }
        }
    }
}
